#include <vector>
#include <nice2d/application.h>
#include <nice2d/background.h>
#include <nice2d/widgets/desktop.h>
#include <nice2d/widgets/draggablelabel.h>
#include <nice2d/widgets/messagelistcontrol.h>

IMPLEMENT_OBJECT(MessageListControlStyle, LayoutStyle)

MessageListControlStyle::MessageListControlStyle()
{
    normalBackground = Background::create(sf::Color(220, 220, 220));
    hoverBackground = normalBackground;

    headerStyle = std::make_shared<LabelStyle>();
    headerStyle->normalBackground = Background::create(sf::Color(128, 128, 128));
    headerStyle->hoverBackground = Background::create(sf::Color(148, 138, 128));
    headerStyle->pressedBackground = Background::create(sf::Color(160, 150, 128));

    labelStyle = std::make_shared<LabelStyle>();
    labelStyle->hMode = HMode::HMode_Left;
    labelStyle->textColor = sf::Color::Transparent;
    labelStyle->normalBackground = Background::create(sf::Color(180, 180, 180, 250));
    labelStyle->hoverBackground = Background::create(sf::Color(180, 180, 180, 250));
    labelStyle->pressedBackground = Background::create(sf::Color(180, 180, 180, 250));
}

MessageListControlStyle::~MessageListControlStyle()
{
}

class MessageListControlData
{
public:
    MessageListControl *control = nullptr;
    std::shared_ptr<DraggableLabel> header = nullptr;
    std::vector<std::shared_ptr<Label>> labels;
    uint32_t current = 0;

    MessageListControlData(MessageListControl *thisControl)
    {
        control = thisControl;
        auto desktop = GET_APPLICATION_COMPONENT(Desktop);
        auto style = desktop->getControlStyle("MessageListControl");
        control->setControlStyle(style);
    }

    void addHeader()
    {
        header = std::make_shared<DraggableLabel>();
        header->setHResizeRule(ControlResizeRule_Fill);
        header->setVResizeRule(ControlResizeRule_Fixed);
        header->setTargetControl(control->as<Control>());
        control->addWidget(header);
    }
};

IMPLEMENT_OBJECT(MessageListControl, VBoxLayout)

MessageListControl::MessageListControl():
    data(new MessageListControlData(this))
{
}

std::shared_ptr<MessageListControl> MessageListControl::create(uint32_t count)
{
    auto control = std::make_shared<MessageListControl>();
    control->setMargin(1.0f);
    control->setSpacing(1.0f);

    control->data->addHeader();

    auto style = control->getTemplateStyle<MessageListControlStyle>();
    control->data->header->setControlStyle(style->headerStyle);

    for (uint32_t i = 0; i < count; i++) {
        auto label = std::make_shared<Label>();
        label->setControlStyle(style->labelStyle);
        label->setSize(style->itemSize.x, style->itemSize.y);
        control->addWidget(label);
        control->data->labels.push_back(label);
    }

    return control;
}

MessageListControl::~MessageListControl()
{
}

std::shared_ptr<Label> MessageListControl::getHeader() const
{
    return data->header;
}

void MessageListControl::addMessage(const sf::String &message, const sf::Color &color)
{
    if (data->current >= data->labels.size()) {
        for (uint32_t i = 0; i < data->current - 1; i++) {
            auto next = data->labels[i + 1];
            data->labels[i]->setText(next->getText());
            data->labels[i]->setTextColor(next->getTextColor());
        }

        data->labels.back()->setTextColor(color);
        data->labels.back()->setText(message);
    } else {
        data->labels[data->current]->setText(message);
        data->labels[data->current]->setTextColor(color);
        data->current ++;
    }
}

void MessageListControl::onStyleChanged()
{
    VBoxLayout::onStyleChanged();

    auto style = getTemplateStyle<MessageListControlStyle>();

    auto itr = data->labels.begin();
    while (itr != data->labels.end()) {
        (*itr)->setControlStyle(style->labelStyle);
        itr ++;
    }
}
